package chalmersbot;

import chalmersbot.Absyn.*;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

/** BNFC-Generated Fold Visitor */
public abstract class FoldVisitor<R,A> implements AllVisitor<R,A> {
    public abstract R leaf(A arg);
    public abstract R combine(R x, R y, A arg);

/* Sentence */
    public R visit(chalmersbot.Absyn.QSentence p, A arg) {
      R r = leaf(arg);
      r = combine(p.qphrase_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.ISentenceD p, A arg) {
      R r = leaf(arg);
      r = combine(p.iphrase_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.ISentence p, A arg) {
      R r = leaf(arg);
      r = combine(p.iphrase_.accept(this, arg), r, arg);
      return r;
    }

/* IPhrase */
    public R visit(chalmersbot.Absyn.ISubNr p, A arg) {
      R r = leaf(arg);
      r = combine(p.numberrule_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.ISub p, A arg) {
      R r = leaf(arg);
      r = combine(p.subject_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.ISubIsSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }

/* QPhrase */
    public R visit(chalmersbot.Absyn.QPhraseSimple p, A arg) {
      R r = leaf(arg);
      r = combine(p.phrase_.accept(this, arg), r, arg);
      return r;
    }

/* Phrase */
    public R visit(chalmersbot.Absyn.QYNVerbSubVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.verb_1.accept(this, arg), r, arg);
      r = combine(p.subject_.accept(this, arg), r, arg);
      r = combine(p.verb_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QYNVerbSubVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.verb_1.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_2.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QYNIsSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QYNIsSubVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordIsSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordIsSubVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordIsSubVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordSubVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.subject_.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordSubVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordSubIsSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordSubIsSubVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      r = combine(p.subject_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordVerbSubVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.verb_1.accept(this, arg), r, arg);
      r = combine(p.subject_.accept(this, arg), r, arg);
      r = combine(p.verb_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordVerbSubVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qword_.accept(this, arg), r, arg);
      r = combine(p.verb_1.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_2.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QInWhichSubIsSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qwinw_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QInWhichSubIsSubVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.qwinw_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QInWhichSubIsSubVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qwinw_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      r = combine(p.subject_3.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QInWhichSubVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qwinw_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QInWhichSubVerbSubVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.qwinw_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_1.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      r = combine(p.verb_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QInWhichSubVerbSubVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qwinw_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_1.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      r = combine(p.verb_2.accept(this, arg), r, arg);
      r = combine(p.subject_3.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QHowManySubVerbSub p, A arg) {
      R r = leaf(arg);
      r = combine(p.qwhow_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QHowManySubVerbSubVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.qwhow_.accept(this, arg), r, arg);
      r = combine(p.subject_1.accept(this, arg), r, arg);
      r = combine(p.verb_1.accept(this, arg), r, arg);
      r = combine(p.subject_2.accept(this, arg), r, arg);
      r = combine(p.verb_2.accept(this, arg), r, arg);
      return r;
    }

/* QWInW */
    public R visit(chalmersbot.Absyn.QWInW_1 p, A arg) {
      R r = leaf(arg);
      r = combine(p.inwrd_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWInW_2 p, A arg) {
      R r = leaf(arg);
      r = combine(p.inwrd_.accept(this, arg), r, arg);
      return r;
    }

/* QWHow */
    public R visit(chalmersbot.Absyn.QWHowMany p, A arg) {
      R r = leaf(arg);
      r = combine(p.manywrd_.accept(this, arg), r, arg);
      return r;
    }

/* QWord */
    public R visit(chalmersbot.Absyn.QWordQWordToken p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordQWhichToken p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordQHowToken p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.QWordQWhatToken p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* AuxVerb */
    public R visit(chalmersbot.Absyn.AuxiliaryVerb p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* IsVrb */
    public R visit(chalmersbot.Absyn.IsVerb p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* Vrb */
    public R visit(chalmersbot.Absyn.RegularVerb p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* ToWrd */
    public R visit(chalmersbot.Absyn.ToWord p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* GoingWrd */
    public R visit(chalmersbot.Absyn.GoingWord p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* Verb */
    public R visit(chalmersbot.Absyn.VerbBasic p, A arg) {
      R r = leaf(arg);
      r = combine(p.verbword_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.VerbIsVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.isvrb_.accept(this, arg), r, arg);
      r = combine(p.vrb_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.VerbGointTo p, A arg) {
      R r = leaf(arg);
      r = combine(p.goingwrd_.accept(this, arg), r, arg);
      r = combine(p.towrd_.accept(this, arg), r, arg);
      r = combine(p.verbword_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.VerbGoing p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.VerbTo p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* VerbWord */
    public R visit(chalmersbot.Absyn.VerbWordVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.vrb_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.VerbWordAux p, A arg) {
      R r = leaf(arg);
      r = combine(p.auxverb_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.VerbWordAuxVerb p, A arg) {
      R r = leaf(arg);
      r = combine(p.auxverb_.accept(this, arg), r, arg);
      r = combine(p.vrb_.accept(this, arg), r, arg);
      return r;
    }

/* InWrd */
    public R visit(chalmersbot.Absyn.InWord p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* Preposition */
    public R visit(chalmersbot.Absyn.Prepositions p, A arg) {
      R r = leaf(arg);
      r = combine(p.inwrd_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.PrepositionsTok p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* NumberRule */
    public R visit(chalmersbot.Absyn.NumberRuleNumberDigitToken p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.NumberRuleNumberTextToken p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* Credit */
    public R visit(chalmersbot.Absyn.CreditNrEC p, A arg) {
      R r = leaf(arg);
      r = combine(p.creditnr_.accept(this, arg), r, arg);
      r = combine(p.ects_.accept(this, arg), r, arg);
      r = combine(p.creditwrd_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.CreditNrE p, A arg) {
      R r = leaf(arg);
      r = combine(p.creditnr_.accept(this, arg), r, arg);
      r = combine(p.ects_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.CreditNrC p, A arg) {
      R r = leaf(arg);
      r = combine(p.creditnr_.accept(this, arg), r, arg);
      r = combine(p.creditwrd_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.CreditE p, A arg) {
      R r = leaf(arg);
      r = combine(p.ects_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.CreditEC p, A arg) {
      R r = leaf(arg);
      r = combine(p.ects_.accept(this, arg), r, arg);
      r = combine(p.creditwrd_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.CreditC p, A arg) {
      R r = leaf(arg);
      r = combine(p.creditwrd_.accept(this, arg), r, arg);
      return r;
    }

/* CreditWrd */
    public R visit(chalmersbot.Absyn.CreditWord p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* Ects */
    public R visit(chalmersbot.Absyn.EctsWord p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* CreditNr */
    public R visit(chalmersbot.Absyn.CreditNrCreditNrToken p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.CreditNrNumberDigitToken p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* Adjective */
    public R visit(chalmersbot.Absyn.AdjectiveAdjectivesToken p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.AdjectiveManyWrd p, A arg) {
      R r = leaf(arg);
      r = combine(p.manywrd_.accept(this, arg), r, arg);
      return r;
    }

/* ManyWrd */
    public R visit(chalmersbot.Absyn.ManyWord p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* SpecialWordToken */
    public R visit(chalmersbot.Absyn.SpecialWordTokenSNounSToken p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SpecialWordTokenSNounEsToken p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* NameRule */
    public R visit(chalmersbot.Absyn.NameRuleNameToken p, A arg) {
      R r = leaf(arg);
      return r;
    }

/* Subject */
    public R visit(chalmersbot.Absyn.SubjectToList p, A arg) {
      R r = leaf(arg);
      r = combine(p.subjectlst_.accept(this, arg), r, arg);
      return r;
    }

/* SubjectLst */
    public R visit(chalmersbot.Absyn.SubjectList p, A arg) {
      R r = leaf(arg);
      r = combine(p.subjectlst_.accept(this, arg), r, arg);
      r = combine(p.subjectwrd_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectListElement p, A arg) {
      R r = leaf(arg);
      r = combine(p.subjectwrd_.accept(this, arg), r, arg);
      return r;
    }

/* SubjectWrd */
    public R visit(chalmersbot.Absyn.SubjectBasic p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectSpecialWord p, A arg) {
      R r = leaf(arg);
      r = combine(p.specialwordtoken_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectDeterminant p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectSmallWord p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectPronoun p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectPeriod p, A arg) {
      R r = leaf(arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectPeriodNr p, A arg) {
      R r = leaf(arg);
      r = combine(p.numberrule_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectName p, A arg) {
      R r = leaf(arg);
      r = combine(p.namerule_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectNumber p, A arg) {
      R r = leaf(arg);
      r = combine(p.credit_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectPreposition p, A arg) {
      R r = leaf(arg);
      r = combine(p.preposition_.accept(this, arg), r, arg);
      return r;
    }
    public R visit(chalmersbot.Absyn.SubjectAdjective p, A arg) {
      R r = leaf(arg);
      r = combine(p.adjective_.accept(this, arg), r, arg);
      return r;
    }


}
